package com.ruoyi.system.common;

import org.apache.commons.net.util.SubnetUtils;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class IpPortOnlineTools {

    public static List<String> cidr2ips(String cidr) {
        SubnetUtils subnetUtils = new SubnetUtils(cidr);
        // 获取 IP 段内的所有 IP 地址
        String[] allIps = subnetUtils.getInfo().getAllAddresses();
        return Arrays.asList(allIps);
    }

    public static List<String> section2ips(String startIp, String endIp) {
        long start = ipToLong(startIp);
        long end = ipToLong(endIp);
        List<String> ipList = new ArrayList<>();
        for (long i = start; i <= end; i++) {
            ipList.add(longToIp(i));
        }
        return ipList;
    }

    public static List<Integer> section2port(String start, String end) {
        int e = Integer.parseInt(end);
        int s = Integer.parseInt(start);
        ArrayList<Integer> integers = new ArrayList<>();
        for (int i = s; i <= e; i++) {
            integers.add(i);
        }
        return integers;
    }


    public static void main(String[] args) {

    }


    public HashMap<String, Boolean> testIP(List<String> ips) throws Exception {
        HashMap<String, Boolean> stringBooleanHashMap = new HashMap<>();
        ExecutorService executor = Executors.newFixedThreadPool(32);
        executor.submit(() -> {
            for (String ip : ips) {
                stringBooleanHashMap.put(ip,isIPOnline(ip));
            }
        });
        executor.shutdown();
        if (executor.awaitTermination(1, TimeUnit.HOURS)) {
            return stringBooleanHashMap;
        } else {
            throw new RuntimeException("线程池超时");
        }
    }

    public HashMap<Integer, Boolean> testPort(String ip, List<Integer> ports) throws Exception{
        HashMap<Integer, Boolean> stringBooleanHashMap = new HashMap<>();
        ExecutorService executor = Executors.newFixedThreadPool(32);
        executor.submit(() -> {
            for (Integer port : ports) {
                stringBooleanHashMap.put(port,isPortOpen(ip,port));
            }
        });
        executor.shutdown();
        if (executor.awaitTermination(1, TimeUnit.HOURS)) {
            return stringBooleanHashMap;
        } else {
            throw new RuntimeException("线程池超时");
        }
    }


    public static boolean isIPOnline(String ip) {
        try {
            InetAddress inet = InetAddress.getByName(ip);
            return inet.isReachable(2000);
        } catch (IOException e) {
            return false;
        }
    }


    public static boolean isPortOpen(String host, int port) {
        try (Socket socket = new Socket()) {
            // 设置超时时间为 2 秒，避免长时间等待
            socket.connect(new java.net.InetSocketAddress(host, port), 2000);
            // 如果能成功连接，说明端口是开放的
            return true;
        } catch (IOException e) {
            // 连接失败，说明端口没有开放
            return false;
        }
    }


//    -------------------------------------------------------------------------------


    // 将 IP 地址转换为长整型
    private static long ipToLong(String ip) {
        String[] ipParts = ip.split("\\.");
        long result = 0;
        for (int i = 0; i < 4; i++) {
            result = result << 8 | Integer.parseInt(ipParts[i]);
        }
        return result;
    }

    // 将长整型转换为 IP 地址
    private static String longToIp(long ip) {
        StringBuilder sb = new StringBuilder();
        for (int i = 3; i >= 0; i--) {
            sb.append((ip >> (i * 8)) & 255);
            if (i > 0) {
                sb.append(".");
            }
        }
        return sb.toString();
    }

}
